from datetime import datetime

from rest_framework import status
from rest_framework.decorators import action
from rest_framework.pagination import PageNumberPagination
from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet
from django.db.models import Prefetch
from common.models import Stage, Module
from common.serializers import StageSerializer, ModuleSerializer, StageModuleSerializer


class StageViewSet(ModelViewSet):
    queryset = Stage.objects.all().filter(is_delete=False)
    serializer_class = StageSerializer

    exists_message = "阶段名已存在"

    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        # 校验数据
        serializer.is_valid(raise_exception=True)

        queryset = self.get_queryset().filter(name=request.data['name'])

        if queryset:
            return Response(data={"message": self.exists_message}, status=status.HTTP_400_BAD_REQUEST)

        serializer.save()

        return Response(serializer.data, status=status.HTTP_201_CREATED)

    def update(self, request, *args, **kwargs):
        instance = self.get_object()

        request.data['update_time'] = datetime.now()

        serializer = self.get_serializer(instance=instance, data=request.data, partial=True)

        serializer.is_valid(raise_exception=True)

        queryset = self.get_queryset().filter(name=request.data['name'])

        if queryset and str(queryset[0].pk) != kwargs[self.lookup_field]:
            return Response(data={"message": self.exists_message}, status=status.HTTP_400_BAD_REQUEST)

        serializer.save()

        return Response(data=serializer.data, status=status.HTTP_200_OK)

    def destroy(self, request, *args, **kwargs):

        queryset = self.get_queryset().filter(pk=kwargs[self.lookup_field])

        if queryset:
            queryset.update(is_delete=True, delete_time=datetime.now())

        return Response(status=status.HTTP_204_NO_CONTENT)

    @action(methods=['DELETE'], detail=False, url_path='batch-remove', url_name='batch-remove')
    def batch_remove(self, request, *args, **kwargs):

        queryset = self.get_queryset().filter(pk__in=request.data)

        if queryset:
            queryset.update(is_delete=True, delete_time=datetime.now())

        return Response(status=status.HTTP_204_NO_CONTENT)

    @action(methods=["GET"], detail=False, url_path="stage-tree", url_name="stage-tree")
    def stage_condition_tree(self, request, *args, **kwargs):
        # 查询所有的阶段信息和对应的模块信息
        queryset = self.get_queryset().prefetch_related(Prefetch("modules", queryset=Module.objects.filter(is_delete=False)))

        serializer = StageModuleSerializer(queryset, many=True, fields=["id", "name", "modules"])

        return Response(data=serializer.data)


class ModuleViewSet(StageViewSet):
    queryset = Module.objects.filter(is_delete=False)

    serializer_class = ModuleSerializer

    exists_message = "模块名已存在"

    pagination_class = PageNumberPagination

    PageNumberPagination.page_size_query_param = "rows"

    def list(self, request, *args, **kwargs):
        paginator = self.paginate_queryset(self.get_queryset().select_related("stage").order_by('id'))

        if paginator:
            # 如果有分页查询、则对分页的结果进行序列化
            serializer = self.get_serializer(paginator, many=True)

            return self.get_paginated_response(serializer.data)

        serializer = self.get_serializer(paginator, many=True)

        return Response(serializer.data)

    def update(self, request, *args, **kwargs):
        instance = self.get_object()

        request.data['update_time'] = datetime.now()

        serializer = self.get_serializer(instance=instance, data=request.data, partial=True)

        serializer.is_valid(raise_exception=True)
        # 在 同一个阶段下 模块名不允许重名
        queryset = self.get_queryset().filter(name=request.data['name'], stage__pk=request.data["stage"])

        if queryset and str(queryset[0].pk) != kwargs[self.lookup_field]:
            return Response(data={"message": self.exists_message}, status=status.HTTP_400_BAD_REQUEST)

        serializer.save()

        return Response(data=serializer.data, status=status.HTTP_200_OK)
